/*
 * Copyright (c) 2014. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package com.dc.gameserver.extComponents.NettyEngine3.service;


import com.alibaba.fastjson.JSON;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;

import javax.annotation.PostConstruct;
import java.nio.charset.Charset;


/**
 * 逻辑数据分解处理
 */
public  abstract class HandleController implements IController {

    @PostConstruct
     public abstract void PostConstruct();
    /**数据采用解析json格式，json数据解析为相应的javaBean*/
    /**
     * 采用fastJson将数据包序列化为javaBean对象
     * 将数据解析为javaBean
     * @param buffer    buffer
     * @param clazz   class
     * @return        Object  javaBean
     */
    @SuppressWarnings("unchecked")
    public Object parseObject(ChannelBuffer buffer,Class clazz){
        Object o=JSON.parseObject(buffer.toString(buffer.readerIndex(),
                buffer.writerIndex() - buffer.readerIndex(), Charset.defaultCharset()).trim(), clazz);
        rebackBuf(buffer);
        return o;
    }


    /**
     *    解析数据包buffer操作方式 字节流
     *      1）包体：length+msg+length+msg ... ...
     *******************************************************************************************/
    /**
     * read a byte (1 code)
     *
     * @param buffer buffer
     * @return byte
     */
    @Override
    public byte readByte(ChannelBuffer buffer) {
        return buffer.readByte();
    }


    /**
     * read a short (2 code)
     *
     * @param buffer buffer
     * @return short
     */
    @Override
    public short readShort(ChannelBuffer buffer) {
        return buffer.readShort();  //To change body of implemented methods use File | Settings | File Templates.
    }


    /**
     * read a short (4 code)
     *
     * @param buffer buffer
     * @return int
     */
    @Override
    public int readInt(ChannelBuffer buffer) {
        return buffer.readInt();  //To change body of implemented methods use File | Settings | File Templates.
    }


    /**
     * @param buffer 待处理数据缓存区
     * @return message
     *         如果默认读取1字节长度的字符串，那么该方法传入buffer将直接返回相应的字符串
     */
    @Override
    public String readStringUTF8(ChannelBuffer buffer) {
        int length=buffer.readByte();
        ChannelBuffer dataBuffer=buffer.readBytes(length);
        return dataBuffer.toString(Charset.forName("UTF-8"));
    }

    /**
     * @param buffer 待处理数据缓存区
     * @param length 读取指定的数据长度
     * @return message
     */
    @Override
    public String readStringUTF8(ChannelBuffer buffer, int length) {
        ChannelBuffer dataBuffer=buffer.readBytes(length);
        return dataBuffer.toString(Charset.forName("UTF-8"));  //To change body of implemented methods use File | Settings | File Templates.
    }


    /**
     * @param buffer 待处理数据缓存区
     * @return message
     *         如果默认读取1字节长度的字符串，那么该方法传入buffer将直接返回相应的字符串
     */
    @Override
    public String readString2(ChannelBuffer buffer) {
        int len=buffer.readByte();
        String str=buffer.toString(buffer.readerIndex(), len, Charset.forName("UTF-8"));
        buffer.skipBytes(len);
        return str;
    }
    /**
     * 解析数据包类型包体：length+msg+length+msg ... ...
     * 数据长，注意要跳过
     * 此函数和readString(ChannelBuffer buffer, int length）功能一样的
     * @param buffer 待处理数据缓存区
     * @param len    数据长度
     * @return
     */
    @Override
    public String readString2(ChannelBuffer buffer, int len) {
        String str=buffer.toString(buffer.readerIndex(), len, Charset.forName("UTF-8"));
        buffer.skipBytes(len);
        return str;
    }


    /**
     * 以gbk编码解析数据string
     * @param buffer buffer
     * @param length     length
     * @return   String
     *            返回GBK编码
     */
    @Override
    public String readStringGBK(ChannelBuffer buffer, int length) {
        ChannelBuffer dataBuffer=buffer.readBytes(length);
        return dataBuffer.toString(Charset.forName("gbk"));  //To change body of implemented methods use File | Settings | File Templates.
    }


    /**
     *  构建数据包 ，处理一级类型数据包
     * 注意：此方法适应的协议是：
     *       paras数据结构-----> length+msg+length+msg ... ...
     *       length: byte(1字节),short（2字节）,int（4字节）
     * @param arg1 类型1  注意 ：args1<0
     * @return  buffer
     */
    public final ChannelBuffer getWriteBufferA(int arg1,Object...paras){
        return this.getWriteBuffer(arg1,0,null,paras);
    }

    /**
     * 构建数据包 ，处理二级类型数据包
     *
     * @param arg1  类型1
     * @param arg2  类型2
     * @param paras 待发送的数据
     *              paras数据-----> length+msg+length+msg ... ...
     *              length: byte(1字节),short（2字节）,int（4字节）
     * @return buffer
     */
    @Override
    public final ChannelBuffer getWriteBufferB(int arg1,int arg2,Object... paras) {
        return this.getWriteBuffer(arg1,arg2,null,paras);  //To change body of implemented methods use File | Settings | File Templates.
    }


    /**
     * 构建数据包
     * @param arg1 类型1
     * @param arg2  类型2
     * @param buffer 申请的buf
     * @param paras 待发送的数据
     *              paras数据-----> length+msg+length+msg ... ...
     *              length: byte(1字节),short（2字节）,int（4字节）
     * @return buffer
     */
    private  final ChannelBuffer getWriteBuffer(int arg1,int arg2,ChannelBuffer buffer,Object...paras){
        if (buffer==null){
            buffer= ChannelBuffers.dynamicBuffer(0x40);
        }
        buffer.writeShort(Short.MIN_VALUE);//包长占2字节
        buffer.writeByte(arg1);
        if (arg2!=0)buffer.writeByte(arg2);
        for (Object para:paras){
            if (para instanceof Byte){
                buffer.writeByte((Byte) para);  // 占1字节
            }else  if ((para instanceof String)){
                buffer.writeBytes(((String) para).getBytes());
            } else if (para instanceof Integer){
                buffer.writeInt((Integer)para);    //占4字节
            }else  if (para instanceof Short){
                buffer.writeShort((Short) para);  //占2字节
            }
        }
        /**包长占2字节，setShort（）*/
        buffer.setShort(0,buffer.writerIndex()-0x2);
        return buffer;
    }
    /**
     * 解码buffer  toByteArray
     * @param buffer   buffer
     * @return   byte[]
     */
    public byte[] BufferToByteArray(ChannelBuffer buffer){
        if (buffer==null)
            return null;
        return buffer.array();
    }

    /**
     * release memory
     *
     * 回收处理完毕的buffer
     * @param buffer       buffer
     */
    public void rebackBuf(ChannelBuffer buffer){
        buffer.clear();
        buffer=null;
    }

    @Override
    public boolean AutoMapper() {
        return true;
    }

}
